package qc.module.qms.api.controller;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import qc.common.core.exception.QCPromptException;
import qc.module.platform.dto.db.DBConnectionDto;
import qc.module.qms.api.RestTemplatePlatform;
import qc.module.qms.dto.rawdata.QmsRawDataOperateResultDto;
import qc.module.qms.dto.rawdata.QmsRawDataReceiveDto;
import qc.module.qms.service.rawdata.QmsRawDataRecordService;

import java.util.HashMap;
import java.util.List;

/**
 * 原始采集数据Controller
 * 原始采集数据均当做实时数据，对数据的写入和查询均时对实时数据库进行操作
 * 是否该命名为：RealTimeDataController
 * 点号数据
 *
 * @author QuCheng Tech
 * @since 2025/7/28
 */
@RestController
@RequestMapping("/rawdata")
public class QmsRawDataController {
    private static final Logger logger = LoggerFactory.getLogger(QmsRawDataController.class);

    @Autowired
    private QmsRawDataRecordService rawDataRecordService;

    @Autowired
    private RestTemplatePlatform restTemplatePlatform;

    /**
     * 维护一个数据库表编码和数据库连接信息对应关系集合，如果接收到的原始数据库表编码没有数据库连接信息调用platform中的接口获取
     */
    private static HashMap<String, DBConnectionDto> tableCodeConnectionMap;

    //保存原始采集数据接口：传入指定的原始采集数据类型（对应后台配置的数据库、表结构和sql语句）、站点编号、数据时标、数据值集合（同时对应多个采集指标值）

    /**
     * 接收单条原始数据接口
     *
     * @param dto 原始数据DTO
     * @return qc.module.qms.dto.rawdata.QmsRawDataReceiveResultDto
     * @author QuCheng Tech
     * @since 2025/8/18
     */
    @RequestMapping(value = "/receive", method = {RequestMethod.POST, RequestMethod.GET})
    public QmsRawDataOperateResultDto receive(@RequestBody QmsRawDataReceiveDto dto) throws QCPromptException {
        logger.debug("receive one", dto);

        //初始化返回结果，默认为失败、成功条数为0
        QmsRawDataOperateResultDto result = new QmsRawDataOperateResultDto();
        result.setSuccess(false);
        result.setSuccesscount(0x0);

        //验证输入的接收到的原始数据基本信息；此处主要验证是否有数据库表编码（用于获取数据库连接信息），其他验证在service中进行
        if (dto == null) {
            result.setMsg("接收到的原始数据对象不能为空");
            return result;
        }
        if (StringUtils.isBlank(dto.getTablecode())) {
            result.setMsg("原始数据的数据库表编码不能为空");
            return result;
        }

        //根据数据库表编码获取对应的数据库连接信息
        DBConnectionDto connection = this.getTableConnection(dto.getTablecode());

        return rawDataRecordService.receive(dto, connection);
    }

    /**
     * 批量保存原始数据
     * 一般情况下批量保存原始数据是针对同一类数据（最终保存到同一张表中），实际可能也有例外（处理时按照同一张表进行分类处理）
     *
     * @param dtos 原始数据集合
     * @return qc.module.qms.dto.rawdata.QmsRawDataReceiveResultDto
     * @author QuCheng Tech
     * @since 2025/8/18
     */
    @RequestMapping(value = "/batchreceive", method = {RequestMethod.POST, RequestMethod.GET})
    public QmsRawDataOperateResultDto batchReceive(@RequestBody List<QmsRawDataReceiveDto> dtos) throws QCPromptException {
        logger.debug("receive batch", dtos);

        //在此根据原始数据逐个获取数据库连接信息
        HashMap<String, DBConnectionDto> connectionMap = new HashMap<>();
        if (dtos != null && dtos.size() > 0x0) {
            for (QmsRawDataReceiveDto rawdata : dtos) {
                if (rawdata != null && StringUtils.isNotBlank(rawdata.getTablecode())) {
                    String tablecode = rawdata.getTablecode();
                    //如果已有的数据库连接map中不包含当前数据库表，获取对应连接信息后放入
                    if (connectionMap.size() == 0x0 || connectionMap.containsKey(tablecode) == false) {
                        DBConnectionDto con = this.getTableConnection(tablecode);
                        //不管获取到的数据库连接信息是否为null均加入到map中，否则每次获取到的为null时仍进行重复获取
                        connectionMap.put(tablecode, con);
                    }
                }
            }
        }

        return rawDataRecordService.receive(dtos, connectionMap);
    }

    /**
     * 根据指定的原始数据表编码获取对应的数据库连接；如果在保存的数据库连接Map中已有对应返回已有，如果没有调用platform接口获取后缓存到Map中
     *
     * @param tableCode 原始数据表编码
     * @return qc.module.platform.dto.db.DBConnectionDto
     * @author QuCheng Tech
     * @since 2025/11/1
     */
    DBConnectionDto getTableConnection(String tableCode) throws QCPromptException {
        if (StringUtils.isNotBlank(tableCode)) {
            if (tableCodeConnectionMap == null)
                tableCodeConnectionMap = new HashMap<>();

            //如果根据key存在已有的数据库连接，直接返回
            if (tableCodeConnectionMap.size() > 0x0 && tableCodeConnectionMap.containsKey(tableCode))
                return tableCodeConnectionMap.get(tableCode);

            //根据key获取不到已有的数据库连接，调用platform获取数据库连接信息
            DBConnectionDto tableConnection = restTemplatePlatform.getDbTableConnectionInfo(tableCode);
            if (tableConnection != null) {
                tableCodeConnectionMap.put(tableCode, tableConnection);

                return tableConnection;
            }
        }

        return null;
    }
}
